home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / seektst.com / SEEKTEST.C next >
Encoding:
C/C++ Source or Header  |  1989-04-04  |  12.1 KB  |  301 lines

  1. /*---------------------------------------------------------------------------
  2.  |  Program SEEKTEST.C                                                      |
  3.  |                                                                          |
  4.  |  This program demonstrates the use of TCHRT in timing seek performance   |
  5.  |  of a PC based hard disk drive.  The method used will determine the total|
  6.  |  seek time of the device which includes actual disk seek, controller     |
  7.  |  overhead, and ROM BIOS overhead.  This is a "real world" measurement    |
  8.  |  of disk performance under actual usage conditions.                      |
  9.  |                                                                          |
  10.  |  Environment: Turbo C 2.0 / Small model                                  |
  11.  |                                                                          |
  12.  |  (c)1989 Ryle Design, P.O. Box 22, Mt. Pleasant, Michigan 48804          |
  13.  ---------------------------------------------------------------------------*/
  14.  
  15. #include <stdio.h>
  16. #include <conio.h>
  17. #include <dos.h>
  18. #include <process.h>
  19.  
  20. #include "tchrt.h"
  21.  
  22. union REGS      inregs,outregs;
  23.  
  24. long unsigned   seek1, seek2, hits1, hits2, seek3, hits3;
  25.  
  26.  
  27. void disk_err(int istat)
  28. /*---------------------------------------------------------------------------
  29.  |  This procedure outputs a description of an INT 13h error status, and    |
  30.  |  halts program exection.                                                 |
  31.  |                                                                          |
  32.  |  Globals referenced: none                                                |
  33.  |                                                                          |
  34.  |  Arguments: (int) istat - status returned from INT 13h in AX if carry    |
  35.  |                           flag set.                                      |
  36.  |                                                                          |
  37.  |  Returns  : void                                                         |
  38.  ---------------------------------------------------------------------------*/
  39. {
  40.     switch (istat)
  41.     {
  42.         case 0x00 : return;                                    /* no error */
  43.  
  44.         case 0x01 : printf("Disk error: Invalid command\n");
  45.                     break;
  46.  
  47.         case 0x02 : printf("Disk error: Address mark not found\n");
  48.                     break;
  49.  
  50.         case 0x03 : printf("Disk error: Disk is write-protected\n");
  51.                     break;
  52.  
  53.         case 0x04 : printf("Disk error: Requested sector not found\n");
  54.                     break;
  55.  
  56.         case 0x05 : printf("Disk error: Reset failed\n");
  57.                     break;
  58.  
  59.         case 0x06 : printf("Disk error: Floppy disk removed\n");
  60.                     break;
  61.  
  62.         case 0x07 : printf("Disk error: Bad parameter table\n");
  63.                     break;
  64.  
  65.         case 0x08 : printf("Disk error: DMA overrun\n");
  66.                     break;
  67.  
  68.         case 0x09 : printf("Disk error: DMA crossed 64KB boundary\n");
  69.                     break;
  70.  
  71.         case 0x0A : printf("Disk error: Bad sector flag set\n");
  72.                     break;
  73.  
  74.         case 0x0B : printf("Disk error: Bad track flag set\n");
  75.                     break;
  76.  
  77.         case 0x0C : printf("Disk error: Requested media type not found\n");
  78.                     break;
  79.  
  80.         case 0x0D : printf("Disk error: Invalid number of sectors on format\n");
  81.                     break;
  82.  
  83.         case 0x0E : printf("Disk error: Control data address mark detected\n");
  84.                     break;
  85.  
  86.         case 0x0F : printf("Disk error: DMA arbitration level out of range\n");
  87.                     break;
  88.  
  89.         case 0x10 : printf("Disk error: Uncorrectable CRC or ECC data error\n");
  90.                     break;
  91.  
  92.         case 0x11 : printf("Disk warning: ECC corrected data error\n");
  93.                     return;
  94.  
  95.         case 0x20 : printf("Disk error: Controller failed\n");
  96.                     break;
  97.  
  98.         case 0x40 : printf("Disk error: Seek failed\n");
  99.                     break;
  100.  
  101.         case 0x80 : printf("Disk error: Disk has timed out\n");
  102.                     break;
  103.  
  104.         case 0xAA : printf("Disk error: Drive not ready\n");
  105.                     break;
  106.  
  107.         case 0xBB : printf("Disk error: Error is undefined\n");
  108.                     break;
  109.  
  110.         case 0xCC : printf("Disk error: Write fault\n");
  111.                     break;
  112.  
  113.         case 0xE0 : printf("Disk error: Status register error\n");
  114.                     break;
  115.  
  116.         case 0xFF : printf("Disk error: Sense operation failed\n");
  117.                     break;
  118.  
  119.         default   : printf("Unknown INT 13 return status %d\n",istat);
  120.                     break;
  121.     }
  122.  
  123.     exit(1);
  124.  
  125. } /* disk_err */
  126.  
  127.  
  128. void test_disk(char disk)
  129. /*---------------------------------------------------------------------------
  130.  |  This function, which contains the actual disk test routines, does the   |
  131.  |  following:                                                              |
  132.  |      1. Seeks the test disk to track 0.                                  |
  133.  |      2. Times 100 calls to seek to track 0.  Since the heads are already |
  134.  |         on track 0, they will not move, and a estimate of the software   |
  135.  |         overhead for each seek call can be made.                         |
  136.  |      3. Times single track seeks to all cylinders (0-1,1-2,2-3,3-4,etc). |
  137.  |         This provides a measurement of single track seek time.           |
  138.  |      4. Seeks from track 0 to all tracks (0-1,0-2,0-3,0-4,etc).  This    |
  139.  |         provides average seek time for the entire disk.                  |
  140.  |      5. The results are reported.                                        |
  141.  |                                                                          |
  142.  |  TC int86() is used to call the ROM BIOS.  There is some software        |
  143.  |  overhead incurred using this method.                                    |
  144.  |                                                                          |
  145.  |  Globals referenced: inregs, outregs.                                    |
  146.  |                                                                          |
  147.  |  Arguments: (char) disk - physical disk # - add to 0x80 for BIOS call.   |
  148.  |                                                                          |
  149.  |  Returns  : void                                                         |
  150.  ---------------------------------------------------------------------------*/
  151. {
  152.     
  153.     int             maxhead,maxcyl,indx;
  154.     unsigned long   seek1,seek2,seek3,hits1,hits2,hits3;
  155.     
  156.     inregs.h.dl = 0x80 + disk;                              /* get disk config */
  157.     inregs.h.ah = 0x08;
  158.     int86(0x13,&inregs,&outregs);
  159.     if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
  160.  
  161.     maxhead = outregs.h.dh;                                 /* move bits to get */
  162.     maxcyl = ((outregs.h.cl & 0xC0) << 2) + outregs.h.ch;   /* heads & tracks   */
  163.  
  164.     printf("\nPhysical drive %d shows %d cylinders, %d heads\n\n",disk,maxcyl+1,maxhead+1);
  165.  
  166.     printf("Starting track to track seek test ...\n");
  167.  
  168.     inregs.h.ah = 0x0C;                                     /* seek command                        */
  169.     inregs.h.ch = 0x00;                                     /* track 0                             */
  170.     inregs.h.cl = 0x01;                                     /* XTs need sector bit set, or no seek */
  171.     inregs.h.dh = 0;                                        /* head 0                              */
  172.     inregs.h.dl = 0x80 + disk;                              /* disk #                              */
  173.  
  174.     int86(0x13,&inregs,&outregs);                           /* seek to track 0 */
  175.     if (outregs.x.cflag != 0) disk_err(outregs.h.ah);       /* stop on error   */
  176.  
  177.     for (indx=0; indx<100; indx++)                          /* seek to 0 100 times to get ave overhead */
  178.     {
  179.         t_entry(2);
  180.         int86(0x13,&inregs,&outregs);
  181.         t_exit(2);
  182.     }
  183.  
  184.     for (indx=1; indx<=maxcyl; indx++)                      /* from zero, single track seek to end of disk */
  185.     {
  186.         inregs.h.ch = indx & 0x00FF;                        /* mask track bits and stuff in cl & ch */
  187.         inregs.h.cl = ((indx & 0x0300) >> 2) + 1;           /* cl sector bit 1 for XTs              */
  188.  
  189.         t_entry(0);
  190.         int86(0x13,&inregs,&outregs);                       /* seek */
  191.         t_exit(0);
  192.  
  193.         if (outregs.x.cflag != 0) disk_err(outregs.h.ah);   /* stop on error */
  194.  
  195.         if ((indx % 100) == 0) printf("%d ",indx);          /* echo to user our progress */
  196.     }
  197.  
  198.  
  199.     printf("\nStarting full disk seek test ...\n");
  200.  
  201.     inregs.h.ch = 0x00;                                     /* back to track 0 for next test */
  202.     inregs.h.cl = 0x01;                                     /* sector bit for XTs            */
  203.     int86(0x13,&inregs,&outregs);                           /* seek                          */
  204.     if (outregs.x.cflag != 0) disk_err(outregs.h.ah);       /* stop on errors                */
  205.  
  206.     for (indx=1; indx<=maxcyl; indx++)                      /* from track 0, seek to all tracks */
  207.     {
  208.         inregs.h.ch = indx & 0x00FF;                        /* mask tracks bits and stuff in cl & ch */
  209.         inregs.h.cl = ((indx & 0x0300) >> 2) + 1;           /* cl sector bit 1 for XTs               */
  210.  
  211.         t_entry(1);
  212.         int86(0x13,&inregs,&outregs);                       /* seek */
  213.         t_exit(1);
  214.  
  215.         if (outregs.x.cflag != 0) disk_err(outregs.h.ah);   /* stop on errors */
  216.  
  217.         if ((indx % 100) == 0) printf("%d ",indx);          /* echo to user our progress */
  218.  
  219.         inregs.h.ch = 0x00;                                 /* go back to track 0 for next seek */
  220.         inregs.h.cl = 0x01;
  221.         int86(0x13,&inregs,&outregs);
  222.         if (outregs.x.cflag != 0) disk_err(outregs.h.ah);
  223.  
  224.     }
  225.  
  226.     t_ask_timer(0,&hits1,&seek1);                           /* query timers */
  227.     t_ask_timer(1,&hits2,&seek2);
  228.     t_ask_timer(2,&hits3,&seek3);
  229.  
  230.     printf("\n\nTest of physical disk %d complete.\n",disk);
  231.     printf("Average track to track seek ........... %7.3f milliseconds\n",((seek1/hits1)/1000.0) );
  232.     printf("Average seek to all tracks ............ %7.3f milliseconds\n",((seek2/hits2)/1000.0) );
  233.     printf("Estimated software overhead per seek .. %7.3f milliseconds\n\n",((seek3/hits3)/1000.0) );
  234.  
  235.     t_reset(0);                                             /* reset all timers */
  236.     t_reset(1);
  237.     t_reset(2);
  238.  
  239. } /* test_disk */
  240.  
  241.  
  242.  
  243. void main(void)
  244. {
  245.     int     indx;
  246.     int     numdisk;
  247.     char    atom;
  248.  
  249.     t_start();                                              /* start TCHRT */
  250.  
  251.     printf("SeekTest V1.00.  TCHRT V2.00 Demonstration Series\n");
  252.     printf("(c)1989 Ryle Design, P.O. Box 22, Mt. Pleasant, Michigan 48804\n\n");
  253.  
  254.     printf("Checking equipment ... ");
  255.  
  256.     inregs.h.ah = 0x08;
  257.     inregs.h.dl = 0x80;
  258.     int86(0x13,&inregs,&outregs);                           /* get available physical disks */
  259.     if (outregs.x.cflag != 0)
  260.     {
  261.         printf("There are no hard disks on this system!\n\n");  /* exit on error */
  262.         printf("SeekTest complete\n");
  263.         exit(0);
  264.     }
  265.  
  266.     numdisk = outregs.h.dl;                                 /* DL has total disks on controller */
  267.     printf("%d physical hard disk(s) found\n\n",numdisk);
  268.  
  269.     printf("*** WARNING -- Do not proceed unless the test disk is backed up!\n\n");     /* A word of advice ... */
  270.  
  271.     do
  272.     {
  273.         for (indx=0; indx<numdisk; indx++)
  274.         {
  275.             printf("%d ... Test disk %d\n",indx,indx);
  276.         }
  277.         printf("%d ... Exit SeekTest\n",numdisk);
  278.  
  279.         do
  280.         {
  281.             printf("Select disk or exit (0-%d) >> ",numdisk);
  282.             atom = getche();
  283.             atom -= '0';
  284.             printf("\n");
  285.         }
  286.         while ( (atom <0) || (atom > numdisk) );
  287.  
  288.         if (atom == numdisk)
  289.         {
  290.             t_stop();                                       /* shut down TCHRT before exit */
  291.             printf("\nSeekTest complete");
  292.             exit(0);
  293.         }
  294.  
  295.         test_disk(atom);
  296.  
  297.     }
  298.     while (atom != numdisk);
  299.  
  300. }
  301.